//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<composition.h>
///	@path	~/src/gui/composite/
///	@date	2008/05/22
///	@desc	Final composition of a layer stack.

#pragma once

#include "xeres.h"

#include "lib/math/color.h"

#include "gui/composite/painter.h"

namespace xeres {

	class Layer;

	/*! 
		\class	Composition
		\brief	Holds a final composition of layers.
	*/
	class Composition
	{
	public:

		/// \ctor
		Composition( Layer * input );

		/// \dtor
		~Composition( void );

		/// \name Composition Rendering Methods
		//@{

		/// \brief	BeginPaint
		bool BeginPaint( const Rect<int>& rect );

		/// \brief	EndPaint
		void EndPaint( void );

		/// \brief	Get painter.
		Painter& painter( void ) { return *m_painter; }

		/// \brief	Get graphics of painter.
		Graphics& graphics( void ) { return painter().GetGraphics(); }

		/// \brief	Get layer.
		Layer& GetLayer( void ) { return m_layer; }

		/// \brief	Visibility test.
		bool IsVisible( const Rect<int>& rect );

		/// \brief	Visibility test.
		bool IsVisible( const Pair<int>& pt );

		//@}

	private:

		//@ data

		Painter *		m_painter;
		Layer&			m_layer;

		// buffer
		byte			m_painterBuffer[ ALIGNOF( sizeof(Painter) / sizeof(byte) , 16 ) ];
		byte			m_bitmapBuffer[ ALIGNOF( sizeof(Gdiplus::Bitmap) / sizeof(byte) , 16 ) ];

	};

#ifdef _GDIPLUS_H
	/*!
		\class ClippingGuard
		\brief protect for overwriting previous clip.
	*/
	class ClippingGuard
	{
	public:

		/// \ctor
		ClippingGuard( Composition& composition );

		/// \dtor
		~ClippingGuard( void );

		/// \brief Restore clip.
		void RestoreClip( void );

	private:

		//@ data
		Composition&		m_composition;
		Gdiplus::Region		m_region;
	};

	/**
		\class TransformGuard
		\brief protected for overwriting previous transform.
	*/
	class TransformGuard
	{
	public:
		/// \ctor
		TransformGuard( Composition& composition );

		/// \ctor
		TransformGuard( Composition& composition , float x , float y );

		/// \dtor
		~TransformGuard( void );

		/// \brief Get transform matrix.
		const Gdiplus::Matrix& GetMatrix( void ) const { return m_matrix; }

		/// \brief Restore transform.
		void RestoreTransform( void );

		/// \brief Reset transform.
		void ResetTransform( float x , float y );
	
	private:

		//@ data
		Graphics&			m_graphics;
		Gdiplus::Matrix		m_matrix;
	};
#endif

} // namespace xeres
